# SuiClientProvider

The `SuiClientProvider` manages the active `SuiClient` that hooks and components use in the dApp
Kit.

## Usage

Place the `SuiClientProvider` at the root of your app and wrap all components that use the dApp Kit
hooks.

`SuiClientProvider` accepts a list of network configurations to create `SuiClient` instances for the
currently active network.

```tsx
import { createNetworkConfig, SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';
import { getFullnodeUrl } from '@mysten/sui/client';

// Config options for the networks you want to connect to
const { networkConfig } = createNetworkConfig({
	localnet: { url: getFullnodeUrl('localnet') },
	mainnet: { url: getFullnodeUrl('mainnet') },
});

function App() {
	return (
		<SuiClientProvider networks={networkConfig} defaultNetwork="localnet">
			<YourApp />
		</SuiClientProvider>
	);
}
```

## Props

- `networks`: A map of networks you can use. The keys are the network names, and the values can be
  either a configuration object (`SuiClientOptions`) or a `SuiClient` instance.
- `defaultNetwork`: The name of the network to use by default when using the `SuiClientProvider` as
  an uncontrolled component.
- `network`: The name of the network to use when using the `SuiClientProvider` as a controlled
  component.
- `onNetworkChange`: A callback when the active network changes.
- `createClient`: A callback when a new `SuiClient` is created (for example, when the active network
  changes). It receives the network name and configuration object as arguments, returning a
  `SuiClient` instance.

## Controlled component

The following example demonstrates a `SuiClientProvider` used as a controlled component.

```tsx
import { createNetworkConfig, SuiClientProvider } from '@mysten/dapp-kit';
import { getFullnodeUrl } from '@mysten/sui/client';
import { useState } from 'react';

// Config options for the networks you want to connect to
const { networkConfig } = createNetworkConfig({
	localnet: { url: getFullnodeUrl('localnet') },
	mainnet: { url: getFullnodeUrl('mainnet') },
});

function App() {
	const [activeNetwork, setActiveNetwork] = useState('localnet' as keyof typeof networks);

	return (
		<SuiClientProvider
			networks={networkConfig}
			network={activeNetwork}
			onNetworkChange={(network) => {
				setActiveNetwork(network);
			}}
		>
			<YourApp />
		</SuiClientProvider>
	);
}
```

## SuiClient customization

The following example demonstrates how to create a custom `SuiClient`.

```tsx
import { SuiClientProvider } from '@mysten/dapp-kit';
import { getFullnodeUrl, SuiClient, SuiHTTPTransport } from '@mysten/sui/client';

// Config options for the networks you want to connect to
const networks = {
	localnet: { url: getFullnodeUrl('localnet') },
	mainnet: { url: getFullnodeUrl('mainnet') },
} satisfies Record<string, SuiClientOptions>;

function App() {
	return (
		<SuiClientProvider
			networks={networks}
			defaultNetwork="localnet"
			createClient={(network, config) => {
				return new SuiClient({
					transport: new SuiHTTPTransport({
						url: 'https://api.safecoin.org',
						rpc: {
							headers: {
								Authorization: 'xyz',
							},
						},
					}),
				});
			}}
		>
			<YourApp />
		</SuiClientProvider>
	);
}
```

## Using the SuiClient from the provider

To use the `SuiClient` from the provider, import the `useSuiClient` function from the
`@mysten/dapp-kit` module.

```tsx
import { useSuiClient } from '@mysten/dapp-kit';

function MyComponent() {
	const client = useSuiClient();

	// use the client
}
```

## Creating a network selector

The dApp Kit doesn't provide its own network switcher, but you can use the `useSuiClientContext`
hook to get the list of networks and set the active one:

```tsx
function NetworkSelector() {
	const ctx = useSuiClientContext();

	return (
		<div>
			{Object.keys(ctx.networks).map((network) => (
				<button key={network} onClick={() => ctx.selectNetwork(network)}>
					{`select ${network}`}
				</button>
			))}
		</div>
	);
}
```

## Using network specific configuration

If your dApp runs on multiple networks, the IDs for packages and other configurations might change,
depending on which network you're using. You can use `createNetworkConfig` to create per-network
configurations that your components can access.

The `createNetworkConfig` function returns the provided configuration, along with hooks you can use
to get the variables defined in your configuration.

- `useNetworkConfig` returns the full network configuration object
- `useNetworkVariables` returns the full variables object from the network configuration
- `useNetworkVariable` returns a specific variable from the network configuration

```tsx
import { createNetworkConfig, SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';
import { getFullnodeUrl } from '@mysten/sui/client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

// Config options for the networks you want to connect to
const { networkConfig, useNetworkVariable } = createNetworkConfig({
	localnet: {
		url: getFullnodeUrl('localnet'),
		variables: {
			myMovePackageId: '0x123',
		},
	},
	mainnet: {
		url: getFullnodeUrl('mainnet'),
		variables: {
			myMovePackageId: '0x456',
		},
	},
});

const queryClient = new QueryClient();

function App() {
	return (
		<QueryClientProvider client={queryClient}>
			<SuiClientProvider networks={networkConfig} defaultNetwork="localnet">
				<WalletProvider>
					<YourApp />
				</WalletProvider>
			</SuiClientProvider>
		</QueryClientProvider>
	);
}

function YourApp() {
	const id = useNetworkVariable('myMovePackageId');

	return <div>Package ID: {id}</div>;
}
```
